import { useCallback, useEffect, useState } from 'react';
import { useDispatch, useSelector } from 'react-redux';
import Taro from '@tarojs/taro';
import { View, Text } from '@tarojs/components';
import {
  AtActionSheet,
  AtActivityIndicator,
  AtButton,
  AtCard,
  AtCheckbox,
  AtDivider,
  AtDrawer,
  AtInput,
  AtRadio,
  AtTextarea,
  AtToast
} from 'taro-ui';
import { RadioOption } from 'taro-ui/types/radio';
import TopIcon, { EIcon, StatusIconTypeArray } from '../../components/top-icon/index.weapp';
import * as ActionTypes from '../../redux/action/types';
import { EStatus, toStatusString } from '../../utils/index';
import { TAssigneeUserInfo, TJobListItem, TUserInfo } from '../../types';
import { TStateType } from '../../redux/reducers';

import './index.scss';

const List = () => {
  const dispatch = useDispatch();
  const originData: TJobListItem[] = useSelector((state: TStateType) => state.jobList);
  const userInfo: TUserInfo = useSelector((state: TStateType) => state.userInfo);
  const assigneeUserInfoState: TAssigneeUserInfo = useSelector(
    (state: TStateType) => state.assigneeUserInfo
  );
  const [jobList, setjobList] = useState<TJobListItem[]>(originData);
  const [checkedList, setCheckedList] = useState<any>([]);
  const [planName, setPlanName] = useState<any>('');
  const [note, setNote] = useState<any>('');
  const [assigneeToValue, setAssigneeToValue] = useState<string>(userInfo.openId);
  const [assigneeToName, setAssigneeToName] = useState<string>(userInfo.nickName);
  const [assigneeOptions, setAssigneeOptions] = useState<RadioOption<string>[]>([
    { label: userInfo.nickName, value: userInfo.openId }
  ]);
  const [errorMessage, setErrorMessage] = useState('');
  const [isOpenFilter, setIsOpenFilter] = useState(false);
  const [isOpenSheet, setIsOpenSheet] = useState(false);
  const [isOpenToast, setIsOpenToast] = useState(false);
  const [isLoading, setIsLoading] = useState(false);

  const getModifyTime = useCallback((item: TJobListItem) => {
    let renderTimeAndAssignee: Date;
    switch (item.status) {
      case EStatus.NoStart:
        renderTimeAndAssignee = new Date(item.createDetials.time);
        break;
      case EStatus.InProgress:
        renderTimeAndAssignee = new Date(item.inProgressDetials.time);
        break;
      case EStatus.Resolved:
        renderTimeAndAssignee = new Date(item.resolvedDetials.time);
        break;
      case EStatus.Ready:
        renderTimeAndAssignee = new Date(item.readyDetials.time);
        break;
      case EStatus.Closed:
        renderTimeAndAssignee = new Date(item.closedDetials.time);
        break;
      default:
        renderTimeAndAssignee = new Date();
        break;
    }
    return renderTimeAndAssignee;
  }, []);

  // const sortJobList = useCallback(
  //   (list: TJobListItem[]) => {
  //     const sortList = list.sort((a, b) => {
  //       return getModifyTime(b).getTime() - getModifyTime(a).getTime();
  //     });
  //     return sortList;
  //   },
  //   [getModifyTime],
  // );

  const getJoblist = useCallback(() => {
    setIsLoading(true);
    Taro.cloud.callFunction({
      name: 'getjoblist',
      data: {
        openId: userInfo.openId,
        // 可以用来获取其他用户的planlist，目前没用到
        assigneeOpenId: assigneeUserInfoState.openId
      },
      success: function (res: any) {
        dispatch({
          type: ActionTypes.RESOLVE_GET_JOBLIST,
          payload: res.result.data
        });
        setIsLoading(false);
      },
      fail: function (err) {
        console.log(err);
      }
    });
  }, [assigneeUserInfoState.openId, dispatch, userInfo.openId]);

  useEffect(() => {
    // const list = sortJobList(originData)
    setjobList(originData);
    if (assigneeUserInfoState.openId) {
      setAssigneeOptions([
        { label: userInfo.nickName, value: userInfo.openId },
        { label: assigneeUserInfoState.nickName, value: assigneeUserInfoState.openId }
      ]);
    } else {
      setAssigneeOptions([{ label: userInfo.nickName, value: userInfo.openId }]);
    }
    setAssigneeToValue(userInfo.openId);
    setAssigneeToName(userInfo.nickName);
  }, [
    assigneeUserInfoState.nickName,
    assigneeUserInfoState.openId,
    originData,
    userInfo.nickName,
    userInfo.openId
  ]);

  const checkboxOption = [
    {
      value: EStatus.NoStart,
      label: 'no start'
    },
    {
      value: EStatus.InProgress,
      label: 'in progress'
    },
    {
      value: EStatus.Resolved,
      label: 'resolved'
    },
    {
      value: EStatus.Ready,
      label: 'ready'
    },
    {
      value: EStatus.Closed,
      label: 'closed'
    }
  ];

  const extraText = useCallback((item: TJobListItem) => {
    switch (item.status) {
      case EStatus.NoStart:
        return `create by: ${item.createDetials.createBy}`;
      case EStatus.InProgress:
        return `modify by: ${item.inProgressDetials.modifyBy}`;
      case EStatus.Resolved:
        return `modify by: ${item.resolvedDetials.modifyBy}`;
      case EStatus.Ready:
        return `modify by: ${item.readyDetials.modifyBy}`;
      case EStatus.Closed:
        return `modify by: ${item.closedDetials.modifyBy}`;
      default:
        return '';
    }
  }, []);

  const noteText = useCallback(
    (item: TJobListItem) => {
      let renderTimeAndModify;
      const modifyTime = getModifyTime(item);
      renderTimeAndModify =
        item.status === EStatus.NoStart
          ? `create time: ${new Date(modifyTime).toLocaleDateString()}`
          : `modify time: ${new Date(modifyTime).toLocaleDateString()}`;
      return renderTimeAndModify + ' - ' + extraText(item);
    },
    [extraText, getModifyTime]
  );

  const renderIcon = useCallback((item: TJobListItem) => {
    return <TopIcon type={EIcon.StatusIcon} name={StatusIconTypeArray[item.status]} size={35} />;
  }, []);

  const handleChange = value => {
    setCheckedList(value);
  };

  const handleFilterClick = () => {
    if (checkedList.length !== 0) {
      const filterList = originData.filter(item => checkedList.includes(item.status));
      setjobList(filterList);
    } else {
      setjobList(originData);
    }
    setIsOpenFilter(false);
  };

  const getNameByOptionValue = useCallback(
    (value: string) => assigneeOptions.filter(option => option.value === value)[0].label,
    [assigneeOptions]
  );

  const handleCreateClick = useCallback(() => {
    const jobItem: TJobListItem = {
      planName,
      createDetials: {
        time: new Date(),
        createBy: userInfo.nickName
      },
      inProgressDetials: {
        time: new Date(),
        modifyBy: userInfo.nickName
      },
      resolvedDetials: {
        time: new Date(),
        modifyBy: userInfo.nickName
      },
      readyDetials: {
        time: new Date(),
        modifyBy: userInfo.nickName
      },
      closedDetials: {
        time: new Date(),
        modifyBy: userInfo.nickName
      },
      status: EStatus.NoStart,
      note,
      assigneeTo: assigneeToName,
      assigneeOpenId: assigneeToValue,
      openId: userInfo.openId
    };

    if (planName) {
      setIsOpenSheet(false);
      setIsLoading(true);
      Taro.cloud.callFunction({
        name: 'addjoblist',
        data: { jobItem },
        success: function () {
          Taro.cloud.callFunction({
            name: 'getjoblist',
            data: {
              openId: userInfo.openId
            },
            success: function (res: any) {
              dispatch({
                type: ActionTypes.RESOLVE_GET_JOBLIST,
                payload: res.result.data
              });
            },
            fail: function (res) {
              console.log(res);
            }
          });
          setPlanName('');
          setNote('');
          setIsLoading(false);
          setAssigneeToValue(userInfo.openId);
          setAssigneeToName(userInfo.nickName);
        }
      });
    } else {
      setErrorMessage('plan name cannot be empty!');
      setIsOpenToast(true);
    }
  }, [
    assigneeToName,
    assigneeToValue,
    dispatch,
    note,
    planName,
    userInfo.nickName,
    userInfo.openId
  ]);

  return (
    <View className='job-list-container'>
      {userInfo.permission && (
        <View className='job-list-header'>
          <Text>Plan List</Text>
          <View className='action-btn'>
            <TopIcon
              type={EIcon.Action}
              name='shuaxin'
              className='single-btn'
              size={50}
              onClick={() => getJoblist()}
            />
            <TopIcon
              type={EIcon.Action}
              name='increase'
              className='single-btn'
              size={50}
              onClick={() => setIsOpenSheet(true)}
            />
            {/* <TopIcon
              type={EIcon.Action}
              name='sort'
              className='single-btn'
              size={45}
              onClick={() => sortJobList()}
            /> */}
            <TopIcon
              type={EIcon.Action}
              name='filter'
              className='single-btn'
              size={45}
              onClick={() => setIsOpenFilter(true)}
            />
          </View>
        </View>
      )}
      <View className='job-list'>
        {isLoading ? (
          <AtActivityIndicator mode='center' content='Loading...' color='white' />
        ) : jobList.length === 0 ? (
          <View className='list-no-data'>
            You can click
            <TopIcon
              type={EIcon.Action}
              name='increase'
              className='no-data-icon'
              size={50}
              onClick={() => setIsOpenSheet(true)}
            />{' '}
            to add a plan.
          </View>
        ) : (
          jobList.map((item: TJobListItem) => {
            return (
              <AtCard
                key={item._id}
                note={noteText(item)}
                extra={`assignee to: ${item.assigneeTo}`}
                title={toStatusString(item.status)}
                renderIcon={renderIcon(item)}
                onClick={() => {
                  Taro.navigateTo({ url: `/pages/plan/index?_id=${item._id}` });
                }}
              >
                {item.planName}
              </AtCard>
            );
          })
        )}
      </View>
      <AtDrawer show={isOpenFilter} onClose={() => setIsOpenFilter(false)} right mask>
        <View className='filter-container'>
          <View className='filter-header'>Filter</View>
          <AtCheckbox
            options={checkboxOption}
            selectedList={checkedList}
            onChange={value => handleChange(value)}
          />
        </View>
        <View className='filter-footer'>
          <View className='footer-container'>
            <AtButton
              type='secondary'
              size='small'
              circle
              className='footer-btn'
              onClick={() => {
                setIsOpenFilter(false);
                setCheckedList([]);
              }}
            >
              Cancle
            </AtButton>
            <AtButton
              type='primary'
              size='small'
              circle
              className='footer-btn'
              onClick={handleFilterClick}
            >
              Ok
            </AtButton>
          </View>
        </View>
      </AtDrawer>
      <AtActionSheet
        isOpened={isOpenSheet}
        cancelText='create'
        title='Add a plan'
        onCancel={() => handleCreateClick()}
        onClose={() => setIsOpenSheet(false)}
      >
        <AtInput
          name='value1'
          title='plan name'
          type='text'
          placeholder='Please enter a plan name'
          required
          value={planName}
          onChange={value => {
            setPlanName(value);
          }}
        />
        <View className='note-content'>
          <View className='note-title'>
            <AtDivider content='NOTE' fontColor='#000' lineColor='#fff' />
          </View>
          <AtTextarea
            value={note}
            onChange={value => {
              setNote(value);
            }}
            maxLength={200}
            placeholder='Please add a note...'
            className='note-body'
          />
        </View>
        <View className='assignee-container'>
          <View className='note-title'>assignee to</View>
          <AtRadio
            options={assigneeOptions}
            value={assigneeToValue}
            onClick={(value: string) => {
              setAssigneeToValue(value);
              setAssigneeToName(getNameByOptionValue(value));
            }}
          />
        </View>
      </AtActionSheet>
      <AtToast
        isOpened={isOpenToast}
        text={errorMessage}
        onClose={() => {
          setErrorMessage('');
          setIsOpenToast(false);
        }}
      ></AtToast>
    </View>
  );
};
export default List;
